#include "PlayerMgr.h"
#include "Net.h"


using namespace su;
using namespace std;


Net::Net(Player& player)
	:m_owner(player)
{
	SetState(LoginState::Logout);
}

Net::~Net()
{
	DelSession();
}

void Net::DelSession()
{
	if (ADFacadeMgr::Ins().FindSession(m_snId))
	{
		ADFacadeMgr::Ins().DelSession(m_snId);
	}
	m_snId.accId = 0;
	m_snId.cid = 0;
}

void Net::SetState(LoginState state)
{
	auto oldState = m_state;
	m_state = state;
	switch (m_state)
	{
	case LoginState::Offline:
		L_COND_V(LoginState::Logout != oldState);
		m_offlineTimer.Stop();
		m_offlineTimer.Start(5 * 60, [this]() {
			LDEBUG("offline time out, set logout");
			L_COND_V(LoginState::Offline == m_state);
			SetState(LoginState::Logout);
			});
		m_owner.FireEvent<EvOffline>();
		break;
	case LoginState::Login:
		m_offlineTimer.Stop();
		SetWaitRelease(false);
		break;
	case LoginState::Logout:
		m_offlineTimer.Stop();
		SetWaitRelease(true);// Net构造函数就调用一次这里，可以让从DB拉去的离线玩家正常释放
		break;
	default:
		LERROR("unknow ", (int)state);
		break;
	}
}


void Net::OnClientDisCon()
{
	if (m_state == LoginState::Login)
	{
		SetState(LoginState::Offline);
	}
	m_snId.Clear();
}

void Net::SendToClient(uint32 cmd, const std::string& msg)
{
	if (const proto::Session* pCon = ADFacadeMgr::Ins().FindSession(m_snId))
	{
		pCon->SendToClient(cmd, msg);
	}
}

void Net::SetWaitRelease(bool enable)
{
	if (enable)
	{
		m_waitReleaseTimer.Start(OFFLINE_CACHE_SPAN, [id=m_owner.Id()]() {
			gPlayerMgr.DelPlayer(id);
		});
	}
	else
	{
		m_waitReleaseTimer.Stop();
	}
}
